"""日志管理器"""

import shutil
import inspect
import gzip, os
import threading
from queue import Queue
from pathlib import Path
from loguru import logger
from datetime import datetime
from src.core.read_conf import get_conf


class Log_manager:

    def __init__(self):
        self.log_dir = Path("logs")
        self.log_queue = Queue()  # 线程安全的队列
        self._setup_logger()
        # 启动日志处理线程
        self.log_thread = threading.Thread(
            target=self._process_logs, daemon=True, name="log.processor"
        )
        self.log_thread.start()
        # 启动日志压缩线程
        self.compress_thread = threading.Thread(
            target=self._auto_compress, daemon=True, name="log.compressor"
        )
        self.compress_thread.start()

    def _setup_logger(self):
        """初始化日志配置"""
        self.log_dir.mkdir(exist_ok=True)
        logger.remove()
        # 控制台日志
        logger.add(
            lambda msg: print(msg, end=""),
            format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <level>{message}</level>",
            level=get_conf("log_level"),
            colorize=True,
        )
        # 文件日志
        logger.add(
            self.log_dir / f"{datetime.now():%Y-%m-%d}.log",
            format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {message}",
            rotation="00:00",
            retention=7,
            level=get_conf("log_level"),
            enqueue=True,
        )

    def _process_logs(self):
        """日志处理线程（替换协程）"""
        while True:
            message, level = self.log_queue.get()  # 阻塞直到有消息
            getattr(logger, level.lower())(message)
            if level == "CRITICAL":
                # 如果是错误级别日志，直接退出程序
                print("出现错误：可能是：权限不足、缺少关键功能组件、配置错误、数据库错误等，正在退出...")
                os._exit(1)

    def _auto_compress(self):
        """日志压缩线程（替换协程）"""
        while True:
            threading.Event().wait(3600)  # 替代 gevent.sleep(3600)
            if datetime.now().hour == 1:
                self._compress_logs()

    def _compress_logs(self):
        """压缩日志实现"""
        for log_file in self.log_dir.glob("*.log"):
            if datetime.now().strftime("%Y-%m-%d") not in log_file.name:
                with log_file.open("rb") as f_in, gzip.open(
                    f"{log_file}.gz", "wb"
                ) as f_out:
                    shutil.copyfileobj(f_in, f_out)
                log_file.unlink()

    # def __getattr__(self, level):
    #     """动态生成日志方法"""
    #     if level in ("INFO", "WARNING", "ERROR", "DEBUG", "CRITICAL"):
    #         return lambda msg: self.log_queue.put((msg, level))
    #     raise AttributeError(level)

    def DEBUG(self, msg):
        """调试日志方法"""
        self.log_queue.put((msg, "DEBUG"))

    def INFO(self, msg):
        """信息日志方法"""
        self.log_queue.put((msg, "INFO"))

    def WARNING(self, msg):
        """警告日志方法"""
        self.log_queue.put((msg, "WARNING"))

    def ERROR(self, msg):
        """错误日志方法"""
        positioning = inspect.stack()[1]
        positioning_msg = f"错误定位在：{positioning.filename}:{positioning.lineno}"
        self.log_queue.put((positioning_msg, "DEBUG"))
        self.log_queue.put((msg, "ERROR"))

    def CRITICAL(self, msg):
        """致命错误日志方法"""
        self.log_queue.put((msg, "CRITICAL"))


log = Log_manager()
